package com.cirnoworks.uhs.server;

import java.io.IOException;
import java.net.SocketAddress;
import java.nio.channels.Selector;

import org.slf4j.LoggerFactory;

import com.cirnoworks.uhs.LinkManager;

public class PortMap {
	private int servicePort;
	private int redirectorPort;
	private RedirectSublink sublink;
	private SocketAddress networkAddress;
	private long lastUpdateTime;
	private final Selector selector;
	private final ControlLink controlLink;
	private boolean dirty = true;
	private final LinkManager manager;

	public PortMap(LinkManager manager, ControlLink controlLink,
			Selector selector) {
		this.selector = selector;
		this.controlLink = controlLink;
		this.manager = manager;
	}

	public int getServicePort() {
		return servicePort;
	}

	public void setServicePort(int servicePort) {
		this.servicePort = servicePort;
	}

	public SocketAddress getNetworkAddress() {
		return networkAddress;
	}

	public void setNetworkAddress(SocketAddress networkAddress) {
		if (sublink != null && !this.networkAddress.equals(networkAddress)) {
			dirty = true;
		}
		this.networkAddress = networkAddress;
	}

	public long getLastUpdateTime() {
		return lastUpdateTime;
	}

	public void setLastUpdateTime(long lastUpdateTime) {
		this.lastUpdateTime = lastUpdateTime;
	}

	public int getRedirectorPort() {
		return redirectorPort;
	}

	public void setRedirectorPort(int redirectorPort) {
		if (this.redirectorPort != redirectorPort) {
			dirty = true;
		}
		this.redirectorPort = redirectorPort;
	}

	public void updateSublinkWhenNecessary() {
		if (dirty) {
			try {
				String word = "Creating";
				if (sublink != null) {
					sublink.close();
					word = "Updating";
				}
				LoggerFactory.getLogger(getClass()).info(
						word + " sublink for " + networkAddress + "@"
								+ redirectorPort + "@" + servicePort);
				sublink = new RedirectSublink(controlLink, selector, manager,
						networkAddress, redirectorPort);
				dirty = false;
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}

	public void close() {
		if (sublink != null) {
			try {
				sublink.close();
			} catch (IOException e) {
				LoggerFactory.getLogger(getClass()).error("", e);
			}
		}
	}

	public RedirectSublink getSublink() {
		return sublink;
	}

}
